package analiseSintatica.Regras.Comandos;

import java.util.LinkedList;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;

public class RegraCmd extends Regra {

    protected String estrutura = "<cmd> ::= <if> | <while> | <do_while> | <return> | <for> | <printf> | <scanf>";


    protected static Regra instancia;

    

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraCmd() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraCmd getInstance() {
        if (instancia == null) {
            instancia = new RegraCmd();
        }
        return (RegraCmd) instancia;
    }

    

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> tokens) throws ErroSintaticoException {
        

    	TiposSemanticos tipos = null;
    	
        if (listaContem(RegraIf.getInstance().getPrimeiro(), tokens.getFirst())) {

               tipos = RegraIf.getInstance().analisar(tokens);


        } else if (listaContem(RegraWhile.getInstance().getPrimeiro(), tokens.getFirst())) {


               tipos = RegraWhile.getInstance().analisar(tokens);


        } else if (listaContem(RegraDoWhile.getInstance().getPrimeiro(), tokens.getFirst())) {


               tipos = RegraDoWhile.getInstance() .analisar(tokens);


        } else if (listaContem(RegraReturn.getInstance().getPrimeiro(), tokens.getFirst())) {


                tipos = RegraReturn.getInstance().analisar(tokens);


        } else if (listaContem(RegraFor.getInstance().getPrimeiro(), tokens.getFirst())) {


               tipos = RegraFor.getInstance().analisar(tokens);


        } else if (listaContem(RegraPrintf.getInstance().getPrimeiro(), tokens.getFirst())) {


                RegraPrintf.getInstance().analisar(tokens);


        } else if (listaContem(RegraScanf.getInstance().getPrimeiro(), tokens.getFirst())) {


               RegraScanf.getInstance().analisar(tokens);

        }else{
            ErroSintaticoException e = new ErroSintaticoException();
            e.addErros("Comando esperado antes do token " + tokens.getFirst().getLexema(), estrutura, tokens.getFirst().getLinha());
            throw e;
        }

        return tipos;
    }

    

    @Override
    protected void setPrimeiro() {
        primeiro = RegraIf.getInstance().getPrimeiro();
        primeiro = getUniao(primeiro, RegraWhile.getInstance().getPrimeiro());
        primeiro = getUniao(primeiro, RegraDoWhile.getInstance().getPrimeiro());
        primeiro = getUniao(primeiro, RegraReturn.getInstance().getPrimeiro());
        primeiro = getUniao(primeiro, RegraFor.getInstance().getPrimeiro());
        primeiro = getUniao(primeiro, RegraPrintf.getInstance().getPrimeiro());
        primeiro = getUniao(primeiro, RegraScanf.getInstance().getPrimeiro());
    }

   
}
